package com.sl.ms.trade.handler.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import com.sl.ms.trade.entity.RefundRecordEntity;
import com.sl.ms.trade.entity.TradingEntity;
import com.sl.ms.trade.enums.RefundStatusEnum;
import com.sl.ms.trade.enums.TradingEnum;
import com.sl.ms.trade.enums.TradingStateEnum;
import com.sl.ms.trade.handler.BeforePayHandler;
import com.sl.ms.trade.service.RefundRecordService;
import com.sl.ms.trade.service.TradingService;
import com.sl.transport.common.exception.SLException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

/**
 * @author wjh
 * @create 2023-09-22 13:56
 */
@Service
public class BeforePayHandlerImpl implements BeforePayHandler {
    
    @Resource
    IdentifierGenerator identifierGenerator;
    
    @Resource
    TradingService tradingService;
    
    @Resource
    RefundRecordService refundRecordService;
    
    @Override
    public void idempotentCreateTrading(TradingEntity tradingEntity) throws SLException {
        //按照订单号获取交易单
        TradingEntity trading = tradingService.findTradByProductOrderNo(tradingEntity.getProductOrderNo());
        if (trading == null) {
            //如果交易单为空，表示这是新的交易单，使用雪花算法生成交易单号
            tradingEntity.setTradingOrderNo((Long) identifierGenerator.nextId(tradingEntity));
            return;
        }
        //如果交易单不为空，表示已经存在了这个交易单，是用户多次发起请求造成的
        TradingStateEnum tradingState = trading.getTradingState();
        if (com.sl.transport.common.util.ObjectUtil.equalsAny(tradingState, TradingStateEnum.YJS,TradingStateEnum.MD)) {
            throw new SLException(TradingEnum.TRADING_STATE_SUCCEED);
        } else if (ObjectUtil.equal(tradingState,TradingStateEnum.FKZ)) {
            if (ObjectUtil.equal(tradingEntity.getTradingChannel(),trading.getTradingChannel())) {
                throw new SLException(TradingEnum.TRADING_STATE_PAYING);
            } else {
                tradingEntity.setId(trading.getId());
                tradingEntity.setTradingOrderNo(Convert.toLong(identifierGenerator.nextId(tradingEntity)));
            }
        } else if (com.sl.transport.common.util.ObjectUtil.equalsAny(tradingState,TradingStateEnum.QXDD,TradingStateEnum.GZ)) {
            tradingEntity.setId(trading.getId());
            tradingEntity.setTradingOrderNo(Convert.toLong(identifierGenerator.nextId(tradingEntity)));
        } else {
            throw new SLException(TradingEnum.PAYING_TRADING_FAIL);
        }
        
    }

    @Override
    public Boolean checkCreateTrading(TradingEntity tradingEntity) {
        boolean flag = ObjectUtil.isAllNotEmpty(tradingEntity,
                tradingEntity.getMemo(),
                tradingEntity.getProductOrderNo(),
                tradingEntity.getEnterpriseId(),
                tradingEntity.getTradingAmount(),
                tradingEntity.getTradingChannel());
        if (!flag) {
            return false;
        }
        //金额不能小于零
        return !NumberUtil.isLessOrEqual(tradingEntity.getTradingAmount(), BigDecimal.valueOf(0));
    }

    @Override
    public void checkRefundTrading(TradingEntity trading) {
        if (ObjectUtil.isEmpty(trading)) {
            throw new SLException(TradingEnum.NOT_FOUND);
        }
        if (trading.getTradingState() != TradingStateEnum.YJS) {
            throw new SLException(TradingEnum.NATIVE_REFUND_FAIL);
        }
        //退款总金额不可超实付总金额
        if (NumberUtil.isGreater(trading.getRefund(),trading.getTradingAmount())) {
            throw new SLException(TradingEnum.BASIC_REFUND_OUT_FAIL);
        }
    }

    /***
     * RefundTrading退款交易幂等性
     */
    @Override
    public RefundRecordEntity idempotentRefundTrading(TradingEntity trading, BigDecimal refundAmount) {
        //查询退款次数，不能大于20次
        List<RefundRecordEntity> recordList = this.refundRecordService.findListByTradingOrderNo(trading.getTradingOrderNo());
        int size = CollUtil.size(recordList);
        if (size >= 20) {
            return null;
        }
        //退款单号
        RefundRecordEntity refundRecord = new RefundRecordEntity();
        refundRecord.setRefundNo(Convert.toLong(this.identifierGenerator.nextId(refundRecord)));
        refundRecord.setTradingOrderNo(trading.getTradingOrderNo());
        refundRecord.setProductOrderNo(trading.getProductOrderNo());
        refundRecord.setEnterpriseId(trading.getEnterpriseId());
        refundRecord.setTradingChannel(trading.getTradingChannel());
        refundRecord.setMemo(trading.getMemo() + "退款（" + size + 1 + "）");
        refundRecord.setRefundStatus(RefundStatusEnum.SENDING);
        refundRecord.setTotal(trading.getTradingAmount());
        refundRecord.setRefundAmount(refundAmount);
        return refundRecord;
    }
}
